#include "BankBranch.h"

BankBranch* BankBranch::p_Instance = NULL;

BankBranch::BankBranch(int branchID, const string city) 
	: branchID(branchID), numOfClients(0), numOfEmployees(0), city(city)
{
	branchDirector	= NULL;
}

BankBranch* BankBranch::Instance()
{
	if (p_Instance == NULL)
	{
		p_Instance = new BankBranch(999, "Tel-Aviv");
	}

	return p_Instance;
}

void BankBranch::addClient(Client& client)
{
	vector<Client*>::iterator	clientsItr = clients.begin();
	clients.insert(clientsItr, &client);
}

bool BankBranch::removeClientById(int id)
{
	try
	{
		Client* client = NULL;
		
		vector<Client*>::const_iterator	itClient;
		vector<Client*>::const_iterator	itClientDelete;

		for (itClient = clients.begin(); itClient != clients.end() && client == NULL; ++itClient)
		{
			if ((**itClient).getId() == id)
			{
				client			= *itClient;
				itClientDelete  = itClient;
			}
		}
	
		if (client != NULL)
		{
			clients.erase(itClientDelete);
			delete client;

			return true;
		}

		
		return false;
	}
	catch (...)
	{
		return false;
	}
}

void BankBranch::addSavingAccountToClientById(int clientId, SavingsAccount& account)
{
	Client* client = getClientByID(clientId);
	client->addSavingAccount(&account);
}

bool BankBranch::deleteClientSavingsAccount(int clientId, int savingAccountId)
{
	try{
		Client* client = getClientByID(clientId);
		client->removeSavingAccount(savingAccountId);
	}
	catch (exception ex)
	{
		return false;
	}

	return true;
}

void BankBranch::addEmployee(Employee& emp)
{
	vector<Employee*>::iterator	employeesItr = employees.begin();
	employees.insert(employeesItr, &emp);
}

bool BankBranch::RemoveEmployee(int id)
{
	try
	{
		Employee* employee = NULL;
		
		vector<Employee*>::const_iterator	itEmployee;
		vector<Employee*>::const_iterator	itEmployeeDelete;

		for (itEmployee = employees.begin(); itEmployee != employees.end() && employee == NULL; ++itEmployee)
		{
			if ((**itEmployee).getId() == id)
			{
				employee			= *itEmployee;
				itEmployeeDelete	= itEmployee;
			}
		}
	
		if (employee != NULL)
		{
			employees.erase(itEmployeeDelete);
			delete employee;

			return true;
		}

		return false;
	}
	catch (...)
	{
		return false;
	}
}

void BankBranch::updateDirector(Director& director)
{
	if (branchDirector != NULL)
	{
		delete branchDirector;
	}

	branchDirector = &director;
}

void BankBranch::updateSalary(int employeeId, int newSalary)
{
	Employee* employee = getEmployeeByID(employeeId);
	employee->setSalary(newSalary);
}

const Director&	BankBranch::getBrachDirector() const
{
	return *branchDirector;
}

int	BankBranch::getNumberOfEmployees() const
{
	return employees.size();
}

int	BankBranch::getNumberOfClients() const
{
	return clients.size();
}

const vector<Employee*>* BankBranch::getClerks() const
{
	vector<Employee*>* clerks = new vector<Employee*>();
	vector<Employee*>::const_iterator	itEmployees;
	

	for (itEmployees = employees.begin(); itEmployees != employees.end(); ++itEmployees)
	{
		if (dynamic_cast<Clerk*>(*itEmployees) != NULL)
		{
			clerks->insert(clerks->end(), *itEmployees);
		}
	}
		
	return clerks;

}

const vector<Employee*>* BankBranch::getCashiers() const
{
	vector<Employee*>* casheirs = new vector<Employee*>();
	vector<Employee*>::const_iterator	itEmployees;
	
	for (itEmployees = employees.begin(); itEmployees != employees.end(); ++itEmployees)
	{
		if (dynamic_cast<Cashier*>(*itEmployees) != NULL)
		{
			casheirs->insert(casheirs->end(), *itEmployees);
		}
	}

	return casheirs;
}

const vector<Client*> BankBranch::getClients()  const
{
	return clients;
}

Client* BankBranch::getClientByID(int id)
{
	vector<Client*>::const_iterator	itClient;

	for (itClient = clients.begin(); itClient != clients.end(); ++itClient)
	{
		if ((**itClient).getId() == id)
		{
			return *itClient;
		}
	}
	
	throw std::exception("Client not found");
}

Employee* BankBranch::getEmployeeByID(int id)
{

	vector<Employee*>::const_iterator	itEmployees;

	for (itEmployees = employees.begin(); itEmployees != employees.end(); ++itEmployees)
	{
		if ((**itEmployees).getId() == id)
		{
			return *itEmployees;
		}
	}

	throw std::exception("Employee not found");
}

ostream& operator<<(ostream& os, const BankBranch& bankBranch)
{
	os << "BankBranch={City=" << bankBranch.city << " Employees=" << bankBranch.getNumberOfEmployees() << " Clients=" << bankBranch.getNumberOfClients() << bankBranch.getBrachDirector();
	return os;
}

BankBranch::~BankBranch()
{
	Client* ptrClient = NULL;
	Employee* ptrEmployee = NULL;

	//Free all clients in the vector
	vector<Client*>::const_iterator	itClients;
	for (itClients = clients.begin(); itClients != clients.end(); ++itClients)
	{
		ptrClient = *itClients;
		
		delete ptrClient;
	}
		
	//Free all employees in the vector
	vector<Employee*>::const_iterator	itEmployees;
	for (itEmployees = employees.begin(); itEmployees != employees.end(); ++itEmployees)
	{
		ptrEmployee = *itEmployees;

		delete ptrEmployee;
	}


	clients.clear();
	employees.clear();

}